#include "iConfig.hpp"

#include <glf/core/mutex.h> 

#if GLF_ENABLE_DEBUGGER
#	include <glf/debugger/profiler.h>
#endif
 
#if __APPLE__
	#include "synchronization_posix_.hpp"
#else
	#include GLFi_HEADER_API(synchronization, GLF_API_THREAD)
#endif


namespace glf
{

Mutex::Mutex(MutexType type)
	: m(GLF_NEW_IMPL(type))
{
	GLF_CHECK_IMPL_SIZE();
}

Mutex::~Mutex()
{
	GLF_DELETE_IMPL();
}

void Mutex::Lock()
{
#if GLF_ENABLE_DEBUGGER
	debugger::SynchronizationScopeEvent dbgScopeEvent(debugger::sMutexEventType, "[glf] Mutex::Lock", (int)this);
#endif

	m.Lock();
}

bool Mutex::TryLock()
{
#if GLF_ENABLE_DEBUGGER
	if(m.TryLock()) {
		debugger::SynchronizationScopeEvent dbgScopeEvent(debugger::sMutexEventType, "[glf] Mutex::Lock", (int)this);
		return true;
	}
	else {
		return false;
	}
#else
	return m.TryLock();
#endif
}

void Mutex::Unlock()
{
#if GLF_ENABLE_DEBUGGER
	debugger::SynchronizationScopeEvent dbgScopeEvent(debugger::sMutexEventType, "[glf] Mutex::Unlock", (int)this);
#endif

	m.Unlock();
}

#if GLF_ENABLE_DEBUGGER

DebuggerMutex::DebuggerMutex(MutexType type) :
	m(*new(mImplBuffer, sizeof(mImplBuffer)) Mutex::Impl(type))
{
	GLF_STATIC_ASSERT_LE(sizeof(Mutex::Impl), sizeof(mImplBuffer));
}

DebuggerMutex::~DebuggerMutex()
{
	m.~Impl();
}

void DebuggerMutex::Lock()
{
	m.Lock();
}

bool DebuggerMutex::TryLock()
{
	return m.TryLock();
}

void DebuggerMutex::Unlock()
{
	m.Unlock();
}

#endif

} //namespace glf

